package com.guomei.service.pay;

import com.alibaba.fastjson.JSON;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.alipay.api.request.AlipayTradeQueryRequest;
import com.alipay.api.request.AlipayTradeWapPayRequest;
import com.alipay.api.response.AlipayTradePagePayResponse;
import com.alipay.api.response.AlipayTradeQueryResponse;
import com.alipay.api.response.AlipayTradeWapPayResponse;
import com.guomei.bean.PayRequest;
import com.guomei.bean.User;
import com.guomei.bean.curse.Course;
import com.guomei.bean.curse.CourseOrder;
import com.guomei.bean.curse.PayResponse;
import com.guomei.bean.curse.domain.DistributeRecord;
import com.guomei.bean.curse.domain.UserDistributorCourseRel;
import com.guomei.bean.curse.domain.UserCourseJoin;
import com.guomei.bean.exam.domain.ExamEnroll;
import com.guomei.configs.AlipayConfig;
import com.guomei.mapper.UserMapper;
import com.guomei.mapper.curse.*;
import com.guomei.service.curse.CourseOrderService;
import com.guomei.service.exam.ExamEnrollService;
import com.guomei.utils.Result;
import com.alibaba.fastjson.JSONObject;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;


@Service
@RequiredArgsConstructor
@Slf4j
@Transactional
public class AlipayService implements PaymentService {
    @Resource
    private ExamEnrollMapper examEnrollMapper;
    @Resource
    private ExamEnrollService examEnrollService;
    private final AlipayClient alipayClient;
    private final AlipayConfig alipayConfig;
    @Resource
    CourseOrderService courseOrderService;
    @Autowired
    private UserMapper userMapper;
    @Resource
    private CourseMapper courseMapper;
    @Resource
    private CourseOrderMapper courseOrderMapper;
    @Resource
    DistributeRecordMapper distributeRecordMapper;
    @Resource
    UserDistributorCourseRelMapper userDistributorCourseRelMapper;
    @Resource
    private UserCourseJoinMapper userCourseJoinMapper;

    /**
     * 创建支付宝支付
     */
    @Override
    public Result<?> createPayment(PayRequest request) throws AlipayApiException {
        PayResponse result = new PayResponse();
        result.setPayType("alipay");
        result.setScene(request.getScene());
        result.setOutTradeNo(request.getOutTradeNo());

        // 根据场景选择不同的支付方式
        if ("web".equals(request.getScene())) {
            result.setPayParams(createWebPayment(request));
        } else if ("h5".equals(request.getScene())) {
            result.setPayParams(createH5Payment(request));
        } else {
            log.info("不支持的支付场景: " + request.getScene());
            return Result.fail("不支持的支付场景");
        }

        return Result.success(result);
    }

    /**
     * 支付宝Web支付
     */
    private String createWebPayment(PayRequest request) throws AlipayApiException {
        AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();
        alipayRequest.setReturnUrl(alipayConfig.getReturnUrlWeb());
        alipayRequest.setNotifyUrl(alipayConfig.getNotifyUrl());

        // 组装请求参数
        String bizContent = String.format("{" +
                        "\"out_trade_no\":\"%s\"," +
                        "\"total_amount\":\"%s\"," +
                        "\"subject\":\"%s\"," +
                        "\"product_code\":\"FAST_INSTANT_TRADE_PAY\"" +
                        "}",
                request.getOutTradeNo(),
                request.getTotalAmount(),
                request.getSubject()
        );
        alipayRequest.setBizContent(bizContent);

        // 调用支付宝接口
        AlipayTradePagePayResponse response = alipayClient.pageExecute(alipayRequest);
        if (response.isSuccess()) {
            return response.getBody(); // 返回支付表单
        } else {
            log.info("创建支付宝Web支付失败：" + response.getMsg());
            return "创建支付宝Web支付失败";
        }
    }

    /**
     * 支付宝H5支付
     */
    private String createH5Payment(PayRequest request) throws AlipayApiException {
        AlipayTradeWapPayRequest alipayRequest = new AlipayTradeWapPayRequest();
        alipayRequest.setReturnUrl(alipayConfig.getReturnUrlH5());
        alipayRequest.setNotifyUrl(alipayConfig.getNotifyUrl());

        // 组装请求参数
        String bizContent = String.format("{" +
                        "\"out_trade_no\":\"%s\"," +
                        "\"total_amount\":\"%s\"," +
                        "\"subject\":\"%s\"," +
                        "\"product_code\":\"QUICK_WAP_WAY\"" +
                        "}",
                request.getOutTradeNo(),
                request.getTotalAmount(),
                request.getSubject()
        );
        alipayRequest.setBizContent(bizContent);

        // 调用支付宝接口
        AlipayTradeWapPayResponse response = alipayClient.pageExecute(alipayRequest);
        if (response.isSuccess()) {
            return response.getBody(); // 返回H5支付表单
        } else {
            log.info("创建支付宝H5支付失败：" + response.getMsg());
            return "创建支付宝H5支付失败";
        }
    }

    /**
     * 处理支付宝异步通知
     */
    @Override
    public boolean handlePaymentNotify(String notifyData) {
        log.info("处理支付宝异步通知: {}", notifyData);
        // 1. 验证签名
        try {
            // 1. 解析通知参数为Map
            Map<String, String> params = parseNotifyData(notifyData);
            log.info("支付宝通知参数：{}", params);

//             2. 验证签名
//             boolean signVerified = verifySignature(params);
//             if (!signVerified) {
//                 log.error("支付宝通知签名验证失败，数据：{}", notifyData);
//                 return false;
//             }

            // 3. 验证通知数据的真实性
            if (!verifyNotifyData(params)) {
                log.error("支付宝通知数据验证失败，数据：{}", notifyData);
                return false;
            }

            // 4. 处理订单业务逻辑
            processOrderBusiness(params);

            log.info("支付宝通知处理成功，订单号：{}", params.get("out_trade_no"));
            return true;

        } catch (Exception e) {
            log.error("处理支付宝通知异常", e);
            return false;
        }
    }


    /**
     * 处理订单业务逻辑（支付成功后调用）
     */
    private void processOrderBusiness(Map<String, String> params) {
        String outTradeNo = params.get("out_trade_no");
        String tradeNo = params.get("trade_no");
        String totalAmount = params.get("total_amount");
        if (outTradeNo.startsWith("EXAM")) {
            // 考试报名订单支付处理
            boolean updateResult = examEnrollService.updatePaymentStatus(outTradeNo, (short) 1, (short) 1, tradeNo, null);
            if (updateResult) {
                log.info("考试报名订单支付成功，订单号：{}，支付宝交易号：{}，金额：{}", outTradeNo, tradeNo, totalAmount);
            } else {
                log.error("更新考试报名支付状态失败，订单号：{}", outTradeNo);
            }
        } else {
            // 示例：更新订单状态为已支付
            CourseOrder order = courseOrderService.getByOrderNo(outTradeNo);
            if (order != null) {
                User user = userMapper.selectById(order.getUserId());
                Course course = courseMapper.selectById(order.getCourseId());
                if (user != null && user.getParentId() != null && course != null) {
                    order.setDistributionUserId(user.getParentId().toString());
                    order.setDistributionAmount(order.getPayAmount().multiply(course.getDistributionRatio()));

                }
                order.setPayStatus((short) 1); // 假设 1 表示已支付
                order.setTradeNo(tradeNo); // 记录支付宝交易号
                order.setOrderStatus((short) 0);
                courseOrderService.update(order);
                log.info("订单支付成功，订单号：{}，支付宝交易号：{}，金额：{}", outTradeNo, tradeNo, totalAmount);
                
                // 为用户创建课程学习记录
                createUserCourseJoinRecord(order.getUserId(), order.getCourseId());
                if (course != null && course.getDistributionType() == 0) {
                    DistributeRecord distributeRecord = new DistributeRecord();
                    distributeRecord.setStudentId(order.getUserId());
                    User user1 = userMapper.selectById(order.getUserId());
                    if (user1 != null && user1.getParentId() != null) {
                        distributeRecord.setDistributorId(user.getParentId());
                        distributeRecord.setCourseId(order.getCourseId());
                        distributeRecord.setOrderId(order.getId());
                        distributeRecord.setActualPayAmount(safeParseBigDecimal(totalAmount));
                        distributeRecord.setDistributionRatio(course.getDistributionRatio());
                        distributeRecord.setDistributeAmount(safeParseBigDecimal(totalAmount).multiply(course.getDistributionRatio()));
                        distributeRecord.setStatus(Short.valueOf("0"));
                        distributeRecordMapper.insert(distributeRecord);
                        log.info("分销类型为：0，插入分销成功");
                    } else {
                        log.info("分销类型为：0，所以查询用户分销人员表，但是无法查询到分销人员信息，不进行分销订单表插入");
                    }
                } else if (course != null && course.getDistributionType() == 1) {
                    UserDistributorCourseRel userDistributorCourseRel = userDistributorCourseRelMapper.selectByStudentAndCourse(order.getUserId(), order.getCourseId());
                    if (userDistributorCourseRel != null) {
                        DistributeRecord distributeRecord = new DistributeRecord();
                        distributeRecord.setStudentId(order.getUserId());
                        distributeRecord.setDistributorId(userDistributorCourseRel.getDistributorId());
                        distributeRecord.setCourseId(order.getCourseId());
                        distributeRecord.setOrderId(order.getId());
                        distributeRecord.setActualPayAmount(safeParseBigDecimal(totalAmount));
                        distributeRecord.setDistributionRatio(course.getDistributionRatio());
                        distributeRecord.setDistributeAmount(safeParseBigDecimal(totalAmount).multiply(course.getDistributionRatio()));
                        distributeRecord.setStatus(Short.valueOf("0"));
                        distributeRecordMapper.insert(distributeRecord);
                        log.info("分销类型为：1，插入分销成功");
                    } else {
                        log.info("分销类型为：1，所以查询用户分销人员表，但是无法查询到分销人员信息，不进行分销订单表插入");
                    }
                }
            }
        }

    }
    
    /**
     * 为用户创建课程学习记录
     * @param userId 用户ID
     * @param courseId 课程ID
     */
    private void createUserCourseJoinRecord(Long userId, Long courseId) {
        try {
            if (userId == null || courseId == null) {
                log.warn("创建用户课程学习记录失败，用户ID或课程ID为空: userId={}, courseId={}", userId, courseId);
                return;
            }
            
            // 检查是否已存在该用户和课程的关联记录
            UserCourseJoin existingRecord = userCourseJoinMapper.selectOne(
                new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<UserCourseJoin>()
                    .eq(UserCourseJoin::getUserId, userId)
                    .eq(UserCourseJoin::getCourseId, courseId)
            );
            
            if (existingRecord != null) {
                log.info("用户课程学习记录已存在，跳过创建: userId={}, courseId={}", userId, courseId);
                return;
            }
            
            // 创建新的用户课程学习记录
            UserCourseJoin userCourseJoin = new UserCourseJoin();
            userCourseJoin.setUserId(userId);
            userCourseJoin.setCourseId(courseId);
            userCourseJoin.setLearnDuration(0); // 初始学习时长为0
            userCourseJoin.setProgress(0); // 初始进度为0%
            userCourseJoin.setStatus((short) 0); // 0-学习中
            userCourseJoin.setLastLearnTime(LocalDateTime.now());
            userCourseJoin.setCreatedTime(LocalDateTime.now());
            userCourseJoin.setUpdatedTime(LocalDateTime.now());
            
            int result = userCourseJoinMapper.insert(userCourseJoin);
            if (result > 0) {
                log.info("成功创建用户课程学习记录: userId={}, courseId={}", userId, courseId);
            } else {
                log.error("创建用户课程学习记录失败: userId={}, courseId={}", userId, courseId);
            }
        } catch (Exception e) {
            log.error("创建用户课程学习记录异常: userId={}, courseId={}", userId, courseId, e);
        }
    }
    
    // 安全的转换方法
    public static BigDecimal safeParseBigDecimal(String amountStr) {
        if (amountStr == null || amountStr.trim().isEmpty()) {
            return BigDecimal.ZERO;
        }
        try {
            return new BigDecimal(amountStr.trim());
        } catch (NumberFormatException e) {
            log.warn("无法解析金额字符串: {}", amountStr, e);
            return BigDecimal.ZERO;
        }
    }
    public static void main(String[] args) {
        String json = "{gmt_create=2025-10-16 00:39:08, charset=UTF-8, gmt_payment=2025-10-16 00:39:28, notify_time=2025-10-16 00:39:28, subject=Comfy UI, sign=HCboxWenCnpO7ON2gY0ei6ZjARNm3ckVqGCdvn7Aj0F7BD7Hj7pcmdHTIDjnsyV+VHHvzLeRwuhzX+DYAeLb/TuXHdeluCcRQVOy9oweU/8ACZ2RsAUCNRmbBiFX1f8xzqUC3zw/7pnW+DaXPJypW4hgwWwZAIXqI0yPcDTmGmDeETkyvimNOulWs2LqoARS/8icyKDvqU0JeQuxAHp/2rv05G7Sm4ycDdiQaUDrIraQBuHvM+hiS8grmTlUfTv66OiqWrcZaENsdFFpsPIogI+8RZGLTd1uTSoQhjgz8ju1/j2mdlyhS7/alLHS+3c+71U/zgIQRpTMxS63EPaOJQ==, merchant_app_id=2021005197650581, buyer_open_id=085DVW9Bv7-tNtksZzIIQw3hz9A551RA5C1R39me1OjfXEc, invoice_amount=0.01, version=1.0, notify_id=2025101601222003928004851440643675, fund_bill_list=[{\"amount\":\"0.01\",\"fundChannel\":\"ALIPAYACCOUNT\"}], notify_type=trade_status_sync, out_trade_no=17605462717867959, total_amount=0.01, trade_status=TRADE_SUCCESS, trade_no=2025101622001404851454265856, auth_app_id=2021005197650581, receipt_amount=0.01, point_amount=0.00, buyer_pay_amount=0.01, app_id=2021005197650581, sign_type=RSA2, seller_id=2088841990138612}";
        System.out.println(json);
    }

    /**
     * 解析通知数据为Map，处理嵌套JSON结构
     */
    private Map<String, String> parseNotifyData(String notifyData) {
        Map<String, String> params = new HashMap<>();

        // 去除首尾的大括号
        String data = notifyData.trim();
        if (data.startsWith("{")) {
            data = data.substring(1);
        }
        if (data.endsWith("}")) {
            data = data.substring(0, data.length() - 1);
        }

        // 分割键值对（处理嵌套JSON中的逗号）
        StringBuilder currentKey = new StringBuilder();
        StringBuilder currentValue = new StringBuilder();
        int braceCount = 0;
        boolean inValue = false;

        for (char c : data.toCharArray()) {
            if (c == '{' || c == '[') {
                braceCount++;
                if (inValue) {
                    currentValue.append(c);
                } else {
                    currentKey.append(c);
                }
            } else if (c == '}' || c == ']') {
                braceCount--;
                if (inValue) {
                    currentValue.append(c);
                } else {
                    currentKey.append(c);
                }
            } else if (c == '=' && braceCount == 0 && !inValue) {
                inValue = true;
            } else if (c == ',' && braceCount == 0) {
                // 处理一个完整的键值对
                if (currentKey.length() > 0 && currentValue.length() > 0) {
                    String key = currentKey.toString().trim();
                    String value = currentValue.toString().trim();

                    // 尝试解析JSON数组或对象
                    if ((value.startsWith("{") && value.endsWith("}")) ||
                            (value.startsWith("[") && value.endsWith("]"))) {
                        try {
                            // 解析为JSON对象或数组
                            Object jsonObj = JSON.parse(value);
                            params.put(key, jsonObj.toString());
                        } catch (Exception e) {
                            // 解析失败则作为字符串存储
                            params.put(key, value);
                        }
                    } else {
                        params.put(key, value);
                    }
                }

                // 重置
                currentKey.setLength(0);
                currentValue.setLength(0);
                inValue = false;
            } else {
                if (inValue) {
                    currentValue.append(c);
                } else {
                    currentKey.append(c);
                }
            }
        }

        // 处理最后一个键值对
        if (currentKey.length() > 0 && currentValue.length() > 0) {
            String key = currentKey.toString().trim();
            String value = currentValue.toString().trim();

            if ((value.startsWith("{") && value.endsWith("}")) ||
                    (value.startsWith("[") && value.endsWith("]"))) {
                try {
                    Object jsonObj = JSON.parse(value);
                    params.put(key, jsonObj.toString());
                } catch (Exception e) {
                    params.put(key, value);
                }
            } else {
                params.put(key, value);
            }
        }

        return params;
    }

    private boolean verifySignature(Map<String, String> params) throws AlipayApiException {
        // 调用支付宝SDK验证签名
        return AlipaySignature.rsaCheckV2(
                params,
                alipayConfig.getPublicKey(),
                "UTF-8",
                "RSA2"  // 签名算法，与支付宝开放平台配置一致
        );
    }

    /**
     * 验证通知数据的真实性
     */
    private boolean verifyNotifyData(Map<String, String> params) {
        // 验证app_id是否匹配
        // if (!alipayConfig.getAppId().equals(params.get("auth_app_id"))) {
        //     return false;
        // }

//         验证交易状态是否为支付成功
        String tradeStatus = params.get("trade_status");
        if (!"TRADE_SUCCESS".equals(tradeStatus)) {
            log.error("交易状态不是成功状态：{}", tradeStatus);
            String outTradeNo = params.get("out_trade_no");
            String tradeNo = params.get("trade_no");
            String totalAmount = params.get("total_amount");
            if (outTradeNo.startsWith("EXAM")){
                ExamEnroll examEnroll = examEnrollMapper.selectByOrderNo(outTradeNo);
                ExamEnroll examEnroll1 = new ExamEnroll();
                examEnroll1.setPayStatus(Short.valueOf("0"));
                examEnroll1.setId(examEnroll.getId());
                examEnroll1.setPayTime(LocalDateTime.now());
                examEnroll1.setStatus(Short.valueOf("2"));
                examEnrollMapper.updateById(examEnroll1);
            }else{
                CourseOrder courseOrder1 = courseOrderMapper.selectByOrderNo(outTradeNo);
                CourseOrder courseOrder = new CourseOrder();
                courseOrder.setPayStatus((short) 0);
                courseOrder.setOrderStatus((short) 0);
                courseOrder.setId(courseOrder1.getId());
                courseOrderService.update(courseOrder);
            }
            return false;
        }

        // 验证订单是否存在
        String outTradeNo = params.get("out_trade_no");
        if (outTradeNo.startsWith("EXAM")) {
            ExamEnroll examEnroll = examEnrollMapper.selectByOrderNo(outTradeNo);
            if (examEnroll == null) {
                log.error("报名费订单不存在，订单号：{}", outTradeNo);
                return false;
            }

            // 验证支付金额是否匹配（支付宝金额单位为元，保留两位小数）
            String totalAmount = params.get("total_amount");
            BigDecimal orderAmount = examEnroll.getAmount();
            if (!orderAmount.equals(new BigDecimal(totalAmount))) {
                log.error("报名费订支付金额不匹配，报名费订订单金额：{}，报名费订支付金额：{}",
                        orderAmount, totalAmount);
                return false;
            }

            // 验证订单当前状态是否为待支付
            if (0 != examEnroll.getPayStatus()) {
                log.error("报名费订订单状态不是待支付，报名费订订单号：{}，当前状态：{}",
                        outTradeNo, examEnroll.getPayStatus());
                return false;
            }
        } else {
            CourseOrder byId = courseOrderService.getByOrderNo(outTradeNo);
            if (byId == null) {
                log.error("订单不存在，订单号：{}", outTradeNo);
                return false;
            }

            // 验证支付金额是否匹配（支付宝金额单位为元，保留两位小数）
            String totalAmount = params.get("total_amount");
            BigDecimal orderAmount = byId.getAmount();
            if (!orderAmount.equals(new BigDecimal(totalAmount))) {
                log.error("支付金额不匹配，订单金额：{}，支付金额：{}",
                        orderAmount, totalAmount);
                return false;
            }

            // 验证订单当前状态是否为待支付
            if (0 != byId.getPayStatus()) {
                log.error("订单状态不是待支付，订单号：{}，当前状态：{}",
                        outTradeNo, byId.getPayStatus());
                return false;
            }
        }
        return true;
    }

    @Override
    public Result<?> queryPayment(String outTradeNo) {
        try {
            log.info("查询支付宝支付状态: outTradeNo={}", outTradeNo);

            // 创建查询请求
            AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();
            JSONObject bizContent = new JSONObject();
            bizContent.put("out_trade_no", outTradeNo);
            request.setBizContent(bizContent.toString());

            // 调用支付宝查询API
            AlipayTradeQueryResponse response = alipayClient.execute(request);

            if (response.isSuccess()) {
                log.info("支付宝查询成功: {}", response.getBody());

                Map<String, Object> queryResult = new HashMap<>();
                queryResult.put("outTradeNo", response.getOutTradeNo());
                queryResult.put("tradeNo", response.getTradeNo());
                queryResult.put("tradeState", response.getTradeStatus());
                queryResult.put("tradeStateDesc", getAlipayTradeStateDesc(response.getTradeStatus()));
                queryResult.put("totalAmount", response.getTotalAmount());
                queryResult.put("buyerPayAmount", response.getBuyerPayAmount());
                queryResult.put("receiptAmount", response.getReceiptAmount());

                if (response.getSendPayDate() != null) {
                    queryResult.put("payTime", response.getSendPayDate());
                }

                log.info("支付宝支付状态查询成功: {}", queryResult);
                return Result.success(queryResult);
            } else {
                log.error("支付宝查询失败: code={}, msg={}, subCode={}, subMsg={}",
                        response.getCode(), response.getMsg(), response.getSubCode(), response.getSubMsg());
                return Result.fail("查询支付状态失败: " + response.getSubMsg());
            }

        } catch (Exception e) {
            log.error("查询支付宝支付状态失败: outTradeNo={}", outTradeNo, e);
            return Result.fail("查询支付状态失败: " + e.getMessage());
        }
    }

    /**
     * 获取支付宝交易状态描述
     */
    private String getAlipayTradeStateDesc(String tradeStatus) {
        if (tradeStatus == null) {
            return "未知状态";
        }

        switch (tradeStatus) {
            case "WAIT_BUYER_PAY":
                return "交易创建，等待买家付款";
            case "TRADE_CLOSED":
                return "未付款交易超时关闭，或支付完成后全额退款";
            case "TRADE_SUCCESS":
                return "交易支付成功";
            case "TRADE_FINISHED":
                return "交易结束，不可退款";
            default:
                return "未知状态: " + tradeStatus;
        }
    }
}
